/*#include<stdio.h>
#include<string.h>
#include<stdlib.h>
#include"system.h"
#include "y.tab.h"*/
// int INTEGER=50,KEYWORD=100;

struct SymTableNode *CreateNewSymTableNode()
{
  int i=0;
  struct SymTableNode *t;
  t =(struct SymTableNode *)malloc(sizeof(struct SymTableNode));
  t->scope=0;
  t->next=NULL;  
  for(i=0;i<HashSize;i++)
    t->table[i] = NULL;	
  return t;
}

struct SymEntry* lookup(char *name,int FuncName)
{
  struct SymEntry *r,*s;
  r=NULL;
  struct SymTableNode *temp;  
  if(name!=NULL)
  {
      int a,i=0,k=name[0]%HashSize; 
      for(a=0;a<=FuncName;a++)
      {
	    temp=global[a];
	    while(temp->next!=NULL)
	    {    
	      s=temp->table[k];   
	      if(s!=NULL)
	      {
		if(strcmp(s->id,name)==0)
		{
		  r=s;
		}    
		else
		{	
		  while(s->next!=NULL)
		  {
		    s=s->next;
		    if(strcmp(s->id,name)==0)
		    {
		      r=s;
		      break;
		    }
		  }
		}      
	      }
	      temp=temp->next;
	    } 
	    s=temp->table[k];  
	    if(s!=NULL)
	    {
	      if(strcmp(s->id,name)==0)
	      {
		r=s;
	      }    
	      else
	      {      
		while(s->next!=NULL)
		{
		  s=s->next;
		  if(strcmp(s->id,name)==0)
		  {
		    r=s;
		    break;
		  }
		}
	      }  
	    }  
      }
  }
  return r;
}
struct SymEntry *InsertSymTable(char *name,int currentScope,int typ,int FuncName)
{
  if(tail[FuncName]->scope!=currentScope)
  {
    //printf("NewScope : %d.\n",currentScope);
    struct SymTableNode *temp;
    temp=CreateNewSymTableNode();
    temp->scope=currentScope;
    tail[FuncName]->next=temp;
    tail[FuncName]=temp;
  }
  struct SymEntry *p;
  p= (struct SymEntry *)malloc(sizeof(struct SymEntry));
  p->id=(char *)malloc(sizeof(char)*strlen(name)+1);
  strcpy(p->id,name);
  p->scope=tail[FuncName]->scope;
  p->type=typ;
  p->next=tail[FuncName]->table[name[0]%HashSize];
  tail[FuncName]->table[name[0]%HashSize]=p;  
  return p;
}

void InitializeSymTable(int KEYWORD)
{
  int counter=0;
  global[0]=CreateNewSymTableNode();
  tail[0]=global[0];
  global[1]=CreateNewSymTableNode();
  tail[1]=global[1];
  global[0]->name=(char*)malloc(sizeof(char)*7);
  //global[1]->name=(char*)malloc(sizeof(char)*100);//Function name is assumed to be less than 100 for now.
  strcpy(global[0]->name,"Global");
  struct SymEntry *p;
  printf("Global created.\n");
  p=InsertSymTable("auto",0,KEYWORD,0);
  p->keywordval=AUTO;  
  //printf("Inserted auto,name : %s , value : %d\n",p->id,p->keywordval);
  p=InsertSymTable("break",0,KEYWORD,0);
  p->keywordval=BREAK;
  p=InsertSymTable("case",0,KEYWORD,0);
  p->keywordval=CASE;
  p=InsertSymTable("char",0,KEYWORD,0);
  p->keywordval=CHAR;
  p=InsertSymTable("const",0,KEYWORD,0);
  p->keywordval=CONST;
  p=InsertSymTable("continue",0,KEYWORD,0);
  p->keywordval=CONTINUE;
  p=InsertSymTable("default",0,KEYWORD,0);
  p->keywordval=DEFAULT;
  p=InsertSymTable("do",0,KEYWORD,0);
  p->keywordval=DO;
  p=InsertSymTable("double",0,KEYWORD,0);
  p->keywordval=DOUBLE;
  p=InsertSymTable("else",0,KEYWORD,0);
  p->keywordval=ELSE;
  p=InsertSymTable("enum",0,KEYWORD,0);
  p->keywordval=ENUM;
  p=InsertSymTable("extern",0,KEYWORD,0);
  p->keywordval=EXTERN;
  p=InsertSymTable("float",0,KEYWORD,0);
  p->keywordval=FLOAT;
  p=InsertSymTable("for",0,KEYWORD,0);
  p->keywordval=FOR;
  p=InsertSymTable("goto",0,KEYWORD,0);
  p->keywordval=GOTO;
  p=InsertSymTable("if",0,KEYWORD,0);
  p->keywordval=IF;
  p=InsertSymTable("int",0,KEYWORD,0);
  p->keywordval=INT;
  p=InsertSymTable("long",0,KEYWORD,0);
  p->keywordval=LONG;
  p=InsertSymTable("register",0,KEYWORD,0);
  p->keywordval=REGISTER;
  p=InsertSymTable("return",0,KEYWORD,0);
  p->keywordval=RETURN;
  p=InsertSymTable("short",0,KEYWORD,0);
  p->keywordval=SHORT;
  p=InsertSymTable("signed",0,KEYWORD,0);
  p->keywordval=SIGNED;
  p=InsertSymTable("sizeof",0,KEYWORD,0);
  p->keywordval=SIZEOF;
  p=InsertSymTable("static",0,KEYWORD,0);
  p->keywordval=STATIC;
  p=InsertSymTable("struct",0,KEYWORD,0);
  p->keywordval=STRUCT;
  p=InsertSymTable("switch",0,KEYWORD,0);
  p->keywordval=SWITCH;
  p=InsertSymTable("typedef",0,KEYWORD,0);
  p->keywordval=TYPEDEF;
  p=InsertSymTable("union",0,KEYWORD,0);
  p->keywordval=UNION;
  p=InsertSymTable("unsigned",0,KEYWORD,0);
  p->keywordval=UNSIGNED;
  p=InsertSymTable("void",0,KEYWORD,0);
  p->keywordval=VOID;
  p=InsertSymTable("volatile",0,KEYWORD,0);
  p->keywordval=VOLATILE;
  p=InsertSymTable("while",0,KEYWORD,0);
  p->keywordval=WHILE;
  p=InsertSymTable("print_t",0,KEYWORD,0);
  p->keywordval=0;
  p->isFunction=1;
  p->linenum=0;
  p->type=400;
  p->scope=0;				     
  p->keywordval=0;	//UNION, INT , etc.
  p->isPointer=0;
  p->isArray=0;
  p->ArrayLimit=0;  
  p->offset=-1;
  p->width=0;
  p->numParameters=1;
  p->ParameterList[0]=(struct Attribute*)malloc(sizeof (struct Attribute));
  p->ParameterList[0] = initAttr(p->ParameterList[0]);
  p->ParameterList[0]->type=400;

  for(counter=1;counter<MaxPar;counter++)
      p->ParameterList[counter]=NULL;
}
void PrintSymTable()
{
  printf("\nPrinting Symbol Table :\n");
  struct SymEntry *s;
  struct SymTableNode *temp;
  int i=0,k=0;  //Biggest Scope found less than or equal to internalScope.
  for(k=0;k<2;k++)
  {
      printf("\nLooking in Function Node %d\n",k);
      temp=global[k];
      while(temp->next!=NULL)
      {  
	  printf("\nLooking in Node %d\n",temp->scope);    
	  for(i=0;i<HashSize;i++)
	  {
	      s=temp->table[i];   	  
	      if(s!=NULL)
	      {
		PrintSymEntry(s);	      	  
		while(s->next!=NULL)
		{
		  s=s->next;
		  PrintSymEntry(s);
		}
		//printf("\n00000000000000000000000000000000000000000\n");
	      }  
	  }    
	  temp=temp->next;
      }
      printf("\nLooking in Node %d\n",temp->scope);    
      for(i=0;i<HashSize;i++)
      {
	  s=temp->table[i];   
	  if(s!=NULL)
	  {
	    PrintSymEntry(s);      
	    while(s->next!=NULL)
	    {
	      s=s->next;
	      PrintSymEntry(s);
	    }
	  }  
      } 
  }
  //printf("\nSearch Finished\n");  
}
void PopSym(int FuncName)
{
  struct SymTableNode* temp;
  temp=global[FuncName];
  while(temp->next->next!=NULL)
  {
      temp=temp->next;
  }
  temp->next=NULL;
  free(tail[FuncName]);
  tail[FuncName]=temp;
}
/*void PopSym()
{
  SymTableNode* temp=global;
  while(temp->next->!=NULL)
  {
      temp=temp->next;
  }
  temp->next=NULL;
  free(tail);
  tail=temp;
}*/

/*int main()
{
  printf("You are in.\n");
  InitializeSymTable();  
  printf("Global Node bana.\n");
  InsertSymTable("ABC1",1,1111);//INTEGER);
  printf("ABC1hmm inserted.\n");
  InsertSymTable("ABC2",1,2222);//FLOAT,(void *)"10.910");
  printf("ABC2 inserted.\n");
  InsertSymTable("BBC3",2,3333);//"POINTER TO CHAR",(void *)"asdad");
  printf("BBC3 inserted.\n");
  struct SymEntry *p;
  p=lookup("BBC3");  
  //p=global->next->table[2];
  printf("Searched for BBC3.Tail ka scope : %d\n",tail->scope);
  if(p==NULL)
    printf("Variable BBC3 not found.\n");
  else printf("Variable found.Name : %s, Type : %d , Scope : %d, Value : %d\n",p->id,p->type,p->scope,p->keywordval);
}*/
